#!/usr/bin/env ruby

# Copyright (c) 2010-2012 Microsoft Corp.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#	http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

require 'rubygems'
require 'ruby-aws'
require 'optparse'

require './include/config'
require './include/proxy'

@config = MOS::Config.create
@mturk  = Amazon::WebServices::MechanicalTurkRequester.new :Host => @config[:Server]

def getRequesterStatistic(statistic, period_unit)
	case period_unit
		when :Lifetime
			period_unit = 'LifeToDate'
		when :Day
			period_unit = 'OneDay'
		when :Week
			period_unit = 'SevenDays'
		when :Month
			period_unit = 'ThirtyDays'
	end

	r = @mturk.GetRequesterStatistic( :Statistic  => statistic,
					  :TimePeriod => period_unit )[:GetStatisticResult][:DataPoint]

	if r.has_key?(:DoubleValue)
		r[:DoubleValue]
	elsif r.has_key?(:LongValue)
		r[:LongValue]
	else
		raise "Received unexpected type"
	end
end

@options = { }
optparse = OptionParser.new do|opts|
	opts.banner = "Usage: #{$0} [options]"
 
	@options[:period_unit]	= :Lifetime
	opts.on( '-a', '--all', 'Lifetime statistics (default)' ) do
	end

	opts.on( '-d', '--days', Integer, 'Cumulative statistics for the last day' ) do
		@options[:period_unit]	= :Day
	end

	opts.on( '-w', '--week', 'Cumulative statistics for the last 7 days' ) do
		@options[:period_unit]	= :Week
	end

	opts.on( '-m', '--month', 'Cumulative statistics for the last 30 days' ) do
		@options[:period_unit]	= :Month
	end

	opts.on( '-h', '--help', 'Display this screen' ) do
		puts opts
		exit
	end

	opts.on_tail("")
	opts.on_tail("This script displays requester statistics from the MTurk account.")
	opts.on_tail("Statistics are not specific to a project, and include all operations performed by the account.")
end

begin
	optparse.parse!
rescue OptionParser::ParseError => e
	$stderr.puts("Error parsing command-line arguments: " + e.message)
	$stderr.puts("Try '#{$0} --help' for more information.")
	exit
end

stats = []
stats << { :Stat => 'NumberAssignmentsAvailable', :Desc => "Assignments Available"	}
stats << { :Stat => 'NumberAssignmentsAccepted',  :Desc => "Assignments Accepted"	}
stats << { :Stat => 'NumberAssignmentsPending',   :Desc => "Assignments Pending"	}
stats << { :Stat => 'NumberAssignmentsApproved',  :Desc => "Assignments Approved"	}
stats << { :Stat => 'PercentAssignmentsApproved', :Desc => "Assignments Approved (%)"	}
stats << { :Stat => 'NumberAssignmentsRejected',  :Desc => "Assignments Rejected"	}
stats << { :Stat => 'PercentAssignmentsRejected', :Desc => "Assignments Rejected (%)"	}
stats << { :Stat => 'NumberAssignmentsReturned',  :Desc => "Assignments Returned"	}
stats << { :Stat => 'NumberAssignmentsAbandoned', :Desc => "Assignments Abandoned"	}
stats << { :Stat => 'TotalRewardPayout',	  :Desc => "Total Reward Payout"	}
stats << { :Stat => 'AverageRewardAmount',	  :Desc => "Average Reward Amount"	}
stats << { :Stat => 'TotalRewardFeePayout',	  :Desc => "Total Reward Fee Payout"	}
stats << { :Stat => 'TotalBonusPayout',		  :Desc => "Total Bonus Payout"		}
stats << { :Stat => 'TotalBonusFeePayout',	  :Desc => "Total Bonus Fee Payout"	}
stats << { :Stat => 'NumberHITsCreated',	  :Desc => "HITs Created"		}
stats << { :Stat => 'NumberHITsCompleted',	  :Desc => "HITs Completed"		}
stats << { :Stat => 'NumberHITsAssignable',	  :Desc => "HITs Assignable"		}
stats << { :Stat => 'NumberHITsReviewable',	  :Desc => "HITs Reviewable"		}
stats << { :Stat => 'EstimatedRewardLiability',   :Desc => "Est. Reward Liability"	}
stats << { :Stat => 'EstimatedFeeLiability',	  :Desc => "Est. Fee Liability"		}
stats << { :Stat => 'EstimatedTotalLiability',	  :Desc => "Est. Total Liability"	}

stats.delete_if do |s|
	if s[:Stat] == 'NumberHITsAssignable' && @options[:period_unit] != :Lifetime
		true
	else
		false
	end
end

tp = Amazon::Util::ThreadPool.new(@config[:ThreadCount])
stats.each do |s|
	tp.addWork(s) do |s|
		s[:Value] = getRequesterStatistic(s[:Stat], @options[:period_unit])
	end
end
tp.finish

statswidth = stats.map { |s| s[:Desc].length }.max
stats.each_index do |i|
	s = stats[i]
	case s[:Value]
		when Integer
			printf("| %2d | %s | %6d |\n",   i+1, s[:Desc].ljust(statswidth), s[:Value])
		when Float
			printf("| %2d | %s | %6.2f |\n", i+1, s[:Desc].ljust(statswidth), s[:Value])
	end
end

